package com.financial.service.heemoney.service.impl;

import com.financial.service.heemoney.connector.SysconfigFeign;
import com.financial.service.heemoney.constants.FinancialPayHeemoneyEnumConstants;
import com.financial.service.heemoney.constants.FinancialPayHeemoneylogEnumConstants;
import com.financial.service.heemoney.convertor.HeemoneyPayConvert;
import com.financial.service.heemoney.convertor.HeemoneyPayQueryConvert;
import com.financial.service.heemoney.convertor.HeemoneyProviderQueryConvert;
import com.financial.service.heemoney.dao.FinancialPayHeemoneyDao;
import com.financial.service.heemoney.dao.FinancialPayHeemoneylogDao;
import com.financial.service.heemoney.domain.FinancialPayHeemoneyDO;
import com.financial.service.heemoney.domain.FinancialPayHeemoneylogDO;
import com.financial.service.heemoney.domain.FinancialReportHeemoneyDO;
import com.financial.service.heemoney.dto.HeemoneyConfigDTO;
import com.financial.service.heemoney.dto.businsess.HeemoneyPayBusinessDTO;
import com.financial.service.heemoney.dto.businsess.HeemoneyPayQueryBusinessDTO;
import com.financial.service.heemoney.dto.commmon.HeemoneyPayCommonDTO;
import com.financial.service.heemoney.dto.commmon.HeemoneyPayQueryCommonDTO;
import com.financial.service.heemoney.dto.commmon.HeemoneyProviderQueryCommonDTO;
import com.financial.service.heemoney.dto.inparameter.HeemoneyPayInParamDTO;
import com.financial.service.heemoney.dto.inparameter.HeemoneyPayQueryInParamDTO;
import com.financial.service.heemoney.dto.param.HeemoneyPayParamDTO;
import com.financial.service.heemoney.dto.param.HeemoneyPayQueryParamDTO;
import com.financial.service.heemoney.service.FinancialPayHeemoneyService;

import com.financial.service.heemoney.utils.JsonUtils;
import com.financial.service.heemoney.utils.OkHttpUtils;
import com.financial.service.heemoney.utils.ResultUtils;
import com.financial.service.heemoney.utils.SignUtils;
import com.financial.service.heemoney.utils.apiresult.ApiResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class FinancialPayHeemoneyServiceImpl implements FinancialPayHeemoneyService {
    @Autowired
    private FinancialPayHeemoneyDao financialPayHeemoneyDao;
    @Autowired
    private SysconfigFeign sysconfigFeign;
    @Autowired
    private OkHttpUtils okHttpUtils;
    @Autowired
    private FinancialPayHeemoneylogDao FinancialPayHeemoneylogDao;

    public static final Logger log = LoggerFactory.getLogger(FinancialPayHeemoneyServiceImpl.class);

    @Override
    public Map<String, Object> pay(HeemoneyPayInParamDTO heemoneyPayInParamDTO) {
        log.info("调用金融中心汇收银服务层支付接口前参数打印：{}", JsonUtils.beanToJson(heemoneyPayInParamDTO));
        //请求汇收银支付明细保存
        this.savePayLog(heemoneyPayInParamDTO);
        //统一按照数据结构进行拼装
        HeemoneyPayBusinessDTO heemoneyPayBusinessDTO = HeemoneyPayConvert.MAPPER.configDTOConvertBusinessDTO(new HeemoneyConfigDTO(), heemoneyPayInParamDTO);
        HeemoneyPayCommonDTO heemoneyPayCommonDTO = HeemoneyPayConvert.MAPPER.configDTOConvertCommonDTO(new HeemoneyConfigDTO(), heemoneyPayInParamDTO);

        HeemoneyPayParamDTO heemoneyPayParamDTO = new HeemoneyPayParamDTO(heemoneyPayCommonDTO, heemoneyPayBusinessDTO);
        log.info("http请求汇收银服务层支付接口入参：{}", heemoneyPayParamDTO.getJsonParam());
        try {
            String resultStr = okHttpUtils.postJsonParams(new HeemoneyConfigDTO().getHeemoneyProviderQuery().getRequest_url(), heemoneyPayParamDTO.getJsonParam());
            log.info("http请求汇收银服务层支付接口回执:{}", resultStr);
            //解析返回数据并保存支付主信息
            this.savePayDetail(heemoneyPayInParamDTO, resultStr);
            //返回调用信息
            return ResultUtils.resultStr(resultStr);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("http请求汇收银服务层支付接口失败订单号为：{}", heemoneyPayInParamDTO.getOut_trade_no());
        }

        return ApiResult.failure();
    }

    //汇收银支付主信息
    private void savePayDetail(HeemoneyPayInParamDTO heemoneyPayInParamDTO, String resultStr) {
        Map<String, Object> changeMap = JsonUtils.jsonToMap(resultStr);

        FinancialPayHeemoneyDO payDO = new FinancialPayHeemoneyDO();
        String result_code = changeMap.get("result_code").toString();
        if (!result_code.equals("SUCCESS")) {
            payDO.setState(FinancialPayHeemoneyEnumConstants.ENUM_STATE_FAIL);
        } else {
            payDO.setState(FinancialPayHeemoneyEnumConstants.ENUM_STATE_SUC);
        }
        payDO.setGmtCreate(new Date());
        payDO.setGmtModified(new Date());
        payDO.setIsDelete(FinancialPayHeemoneyEnumConstants.ENUM_ISDELETE_UNDEL);
        BeanUtils.copyProperties(heemoneyPayInParamDTO, payDO);
        financialPayHeemoneyDao.save(payDO);

    }


    //汇收银支付请求参数日志保存
    private void savePayLog(HeemoneyPayInParamDTO heemoneyPayInParamDTO) {

        FinancialPayHeemoneylogDO paylogDO = new FinancialPayHeemoneylogDO();
        BeanUtils.copyProperties(heemoneyPayInParamDTO, paylogDO);
        paylogDO.setGmtCreate(new Date());
        paylogDO.setGmtModified(new Date());
        paylogDO.setIsDelete(FinancialPayHeemoneylogEnumConstants.ENUM_ISDELETE_UNDEL);
        FinancialPayHeemoneylogDao.save(paylogDO);


    }

    @Override
    public Map<String, Object> query(HeemoneyPayQueryInParamDTO heemoneyPayQueryInParamDTO) {
        Map<String, Object> resultMap = null;
        log.info("调用金融中心汇收银支付单查询接口前参数打印：{}", JsonUtils.beanToJson(heemoneyPayQueryInParamDTO));
        HeemoneyPayQueryCommonDTO heemoneyPayQueryCommonDTO = HeemoneyPayQueryConvert.MAPPER.configConvertCommonDTO(new HeemoneyConfigDTO(), heemoneyPayQueryInParamDTO);
        HeemoneyPayQueryBusinessDTO heemoneyPayQueryBusinessDTO = HeemoneyPayQueryConvert.MAPPER.converBusinessDTO(heemoneyPayQueryInParamDTO);
        //拼接接口业务参数
        HeemoneyPayQueryParamDTO heemoneyPayQueryParamDTO = new HeemoneyPayQueryParamDTO(heemoneyPayQueryCommonDTO, heemoneyPayQueryBusinessDTO);
        log.info("http请求汇收银服务层订单查询接口入参：{}", heemoneyPayQueryParamDTO.getJsonParam());
        try {
            String resultStr = okHttpUtils.postJsonParams(new HeemoneyConfigDTO().getHeemoneyPayQuery().getRequest_url(), heemoneyPayQueryParamDTO.getJsonParam());
            log.info("http请求汇收银服务层订单查询接口回执:{}", resultStr);
            //处理回执信息封装返回调用方
            Map<String, Object> changeMap = JsonUtils.jsonToMap(resultStr);
            String result_code = changeMap.get("result_code").toString();
            if (result_code.equals("SUCCESS")) {
                resultMap = new HashMap<>();
                resultMap.put("out_trade_no", changeMap.get("out_trade_no"));
                resultMap.put("channel_type", changeMap.get("channel_type"));
                resultMap.put("trade_status", changeMap.get("trade_status"));
                resultMap.put("total_fee", changeMap.get("total_fee"));
            }
            //返回调用信息
            return ApiResult.success(resultMap);
        } catch (Exception e1) {
            e1.printStackTrace();
            log.error("http请求汇收银服务层订单查询接口失败订单号为：{}", heemoneyPayQueryInParamDTO.getOut_trade_no());
        }
        return ApiResult.failure();
    }

    @Override
    public Map<String, Object> payBackAsyn(String asynParam) {

        log.info("FinancialPayHeemoneyServiceImpl---------------金融中心汇收银支付异步接口回执参数：{}", JsonUtils.beanToJson(asynParam));
        //验证签名信息
        ApiResult apiResult = null;
        //封装返回值
        Map<String, Object> resultMap = new HashMap<>();
        try {
            boolean b = SignUtils.verifySign(asynParam);
            log.info("FinancialPayHeemoneyServiceImpl--------------汇收银商户支付异步回执签名验证结果：{}", b);

            Map<String, Object> changeMap = JsonUtils.jsonToMap(asynParam);
            //解析返回值并保存异步回执
            this.saveAsynInfo(changeMap);
            if (changeMap.get("result_msg").equals("SUCCESS")) {
                //拼接调用者返回值
                resultMap.put("out_trade_no", changeMap.get("out_trade_no"));
                resultMap.put("channel_type", changeMap.get("channel_type"));
                resultMap.put("trade_status", changeMap.get("trade_status"));
                resultMap.put("total_fee", changeMap.get("total_fee"));
            }
            return ApiResult.success(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("FinancialPayHeemoneyServiceImpl---------汇收银支付异步回执返回失败");
        }
        return ApiResult.failure();
    }

    private void saveAsynInfo(Map<String, Object> changeMap) {
        FinancialPayHeemoneyDO payHeemoneyDO = new FinancialPayHeemoneyDO();

        payHeemoneyDO.setState(FinancialPayHeemoneyEnumConstants.ENUM_STATE_SUC);
        payHeemoneyDO.setIsDelete(FinancialPayHeemoneyEnumConstants.ENUM_ISDELETE_UNDEL);
        payHeemoneyDO.setGmtModified(new Date());
        payHeemoneyDO.setGmtCreate(new Date());
        payHeemoneyDO.setChannelType(changeMap.get("channel_type").toString());
        payHeemoneyDO.setOutTradeNo(changeMap.get("out_trade_no").toString());
        payHeemoneyDO.setResponseType(FinancialPayHeemoneyEnumConstants.ENUM_RESPONSETYPE_ASYNC);
        payHeemoneyDO.setReturnMessage("SUCCESS");
        payHeemoneyDO.setTotalFee(new BigDecimal(changeMap.get("total_fee").toString()));
        financialPayHeemoneyDao.save(payHeemoneyDO);
    }


    @Override
    public FinancialPayHeemoneyDO get(Integer id) {
        return financialPayHeemoneyDao.get(id);
    }

    @Override
    public List<FinancialPayHeemoneyDO> list(Map<String, Object> map) {
        return financialPayHeemoneyDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return financialPayHeemoneyDao.count(map);
    }

    @Override
    public int save(FinancialPayHeemoneyDO financialPayHeemoney) {
        return financialPayHeemoneyDao.save(financialPayHeemoney);
    }

    @Override
    public int update(FinancialPayHeemoneyDO financialPayHeemoney) {
        return financialPayHeemoneyDao.update(financialPayHeemoney);
    }

    @Override
    public int remove(Integer id) {
        return financialPayHeemoneyDao.remove(id);
    }

    @Override
    public int batchRemove(Integer[] ids) {
        return financialPayHeemoneyDao.batchRemove(ids);
    }

}
